package views;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;

import javax.swing.AbstractListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import org.apache.directory.mavibot.btree.FileParse;
import org.apache.directory.mavibot.btree.GraphCreation;
import org.apache.directory.mavibot.btree.GraphTableData;
import org.apache.directory.mavibot.btree.exception.RecordManagerException;

import dataModel.mainPageData;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;


/*
 * Licensed to the Apache Software Foudation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * � License �) ; you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * � AS IS � BASIS, WITHOUT WARRANTIES OR CONDITION OF ANY
 * KIND, either express or implied. See the License for the
 * specific langage governing permissions and limitations
 * under the License.
 *
 */

/**
 * 
 * author <a href=� mailto :dev@directory.apache.org �> Apache Directory Project</a>
 * Class to build the GUI for the BtreeViewer
 *
 */
public class MainPage extends JFrame {

	private static final long serialVersionUID = 1L;
	/** The content Pane to add the Panels */
	private JPanel contentPane;
	/** The textField for the File Path */
	private JTextField fileLocationTxt;
	/** The file chooser to select the Btree */
	private JFileChooser fileChooser;
	/** The table containing the informations and the values in the node */
	public static JTable informationTable;
	/** The panel containing the visualization of the btree */
	public static JPanel btreeContainerPanel = null;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		
		try {
		    UIManager.setLookAndFeel("com.jtattoo.plaf.hifi.HiFiLookAndFeel");
		}
		catch (Exception e) {
		    try {
		    	// If we do not have the Nimbus installed (older JDK) we use the system look and feel class
				UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName() );
			} 
		    catch (Exception e1) {
				JOptionPane.showMessageDialog( null, "There was an error getting the cross Platform look and feel" );
			} 
		}
		
		
		EventQueue.invokeLater(new Runnable()
		{
			public void run()
			{
				try
				{
					MainPage frame = new MainPage();
					frame.setExtendedState( MAXIMIZED_BOTH );
					frame.setMinimumSize( new Dimension( 600,600 ) );
					frame.setVisible( true );
				} 
				catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public MainPage()
	{
		setTitle( "BTreeViewer" );
		setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		setSize( new Dimension( dim.width/2,dim.height/2 ) );
		setLocationRelativeTo( null );
		contentPane = new JPanel();
		contentPane.setBorder( new EmptyBorder( 5, 5, 5, 5 ) );
		setContentPane( contentPane );
		contentPane.setLayout( new GridLayout( 1, 0, 0, 0 ) );
		
		final JTabbedPane tabbedPane = new JTabbedPane( JTabbedPane.TOP );
		contentPane.add( tabbedPane );
		
		JPanel mainPagePanel = new JPanel();
		tabbedPane.addTab("Main Menu", null, mainPagePanel, null);
		mainPagePanel.setLayout( new GridLayout( 0, 2, 0, 5 ) );
		
		JPanel filePickPanel = new JPanel();
		filePickPanel.setForeground( new Color( 0, 128, 128) );
		mainPagePanel.add( filePickPanel );
		GridBagLayout gbl_filePickPanel = new GridBagLayout();
		gbl_filePickPanel.columnWidths = new int[] {15, 200, 0, 40};
		gbl_filePickPanel.rowHeights = new int[] {0, 0, 0, 0, 0, 0, 0, 0, 123};
		gbl_filePickPanel.columnWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
		gbl_filePickPanel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
		filePickPanel.setLayout( gbl_filePickPanel );
		
		JLabel lblexplanation = new JLabel("Select a file to visualize its btree : ");
		lblexplanation.setFont( new Font( "Arial Bold" , Font.CENTER_BASELINE , 20));
		GridBagConstraints gbc_lblVeuillezChoisirUn = new GridBagConstraints();
		gbc_lblVeuillezChoisirUn.insets = new Insets( 0, 0, 5, 5 );
		gbc_lblVeuillezChoisirUn.gridx = 1;
		gbc_lblVeuillezChoisirUn.gridy = 4;
		filePickPanel.add( lblexplanation, gbc_lblVeuillezChoisirUn );
		
		fileLocationTxt = new JTextField();
		GridBagConstraints gbc_fileLocationTxt = new GridBagConstraints();
		gbc_fileLocationTxt.insets = new Insets( 0, 0, 5, 5 );
		gbc_fileLocationTxt.fill = GridBagConstraints.HORIZONTAL;
		gbc_fileLocationTxt.gridx = 1;
		// Test
		gbc_fileLocationTxt.gridy = 7;
		filePickPanel.add( fileLocationTxt, gbc_fileLocationTxt );
		fileLocationTxt.setColumns( 10 );
		
		
		JPanel treeVizualisationPanel = new JPanel();
		tabbedPane.addTab( "Visualize Graph", null, treeVizualisationPanel, null );
		treeVizualisationPanel.setLayout( new GridLayout(0, 2, 0, 0) );
		
		btreeContainerPanel = new JPanel();
		treeVizualisationPanel.add( btreeContainerPanel );
		btreeContainerPanel.setLayout( new BorderLayout() );
		
		
		JPanel graphListPanel = new JPanel();
		mainPagePanel.add(graphListPanel);
		graphListPanel.setLayout( new GridLayout( 1, 0, 0, 0 ) );
		
		final JList<String> graphNames = new JList<String>();
		graphNames.setBorder( new LineBorder( new Color( 0, 0, 0 ), 1, true ) );
		graphNames.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
		
		
		graphNames.addMouseListener(new MouseListener() {
			
			@Override
			public void mouseClicked(MouseEvent e)
			{
				if (e.getClickCount() == 2)
				{
					FileParse.chooseBtree( graphNames.getSelectedValue() );
					
					// We intialize the graph
					GraphCreation.initializeGraph();
					GraphCreation.vv.setSize( btreeContainerPanel.getSize() );
					btreeContainerPanel.removeAll();
					tabbedPane.setSelectedIndex( 1 );
					
					GraphZoomScrollPane graphScrollPane = new GraphZoomScrollPane( GraphCreation.vv );

					btreeContainerPanel.add( graphScrollPane );
					
					// Adding the label displaying the selected btree name
					StringBuilder labelName = new StringBuilder( "Btree: " );
					labelName.append( FileParse.btreeName );
					JLabel treeInformation = new JLabel( labelName.toString() );
					treeInformation.setFont( new Font( "Arial Bold" , Font.BOLD , 20 ) );
					btreeContainerPanel.add( treeInformation,BorderLayout.NORTH );
				}
			}

			@Override
			public void mouseEntered(MouseEvent e)
			{
				// TODO Auto-generated method stub
			}

			@Override
			public void mouseExited(MouseEvent e)
			{
				// TODO Auto-generated method stub
			}

			@Override
			public void mousePressed(MouseEvent e)
			{
				// TODO Auto-generated method stub
			}

			@Override
			public void mouseReleased(MouseEvent e)
			{
				// TODO Auto-generated method stub
			}
		});
		
		addComponentListener(new ComponentListener() {
			
			@Override
			public void componentShown(ComponentEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void componentResized(ComponentEvent e) {
				try 
				{
					//GraphCreation.vv.setSize( btreeContainerPanel.getSize() );
					GraphCreation.centerVisualization( true );
					GraphCreation.vv.repaint();
				}
				catch (Exception exc)
				{
					// Catching exception at the launching of the app
				}
				
			}
			
			@Override
			public void componentMoved(ComponentEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void componentHidden(ComponentEvent e) {
				// TODO Auto-generated method stub
				
			}
		});
		
		graphListPanel.add( graphNames );
		
		JButton fileChooseButton = new JButton( "Choose File" );
		fileChooseButton.addActionListener(new ActionListener() {
			@SuppressWarnings({ "unchecked", "rawtypes" })
			public void actionPerformed(ActionEvent arg0) {
				fileChooser = new JFileChooser();
				fileChooser.showOpenDialog( null );
				try {
					btreeContainerPanel.removeAll();
					mainPageData.chosenFile = fileChooser.getSelectedFile().getCanonicalPath();
					fileLocationTxt.setText( mainPageData.chosenFile );
					graphNames.setModel( new AbstractListModel() {
						/**
						 * 
						 */
						private static final long serialVersionUID = 1L;
						String[] values = FileParse.loadGraphs( fileChooser.getSelectedFile().getAbsolutePath() );
						public int getSize() {
							return values.length;
						}
						public Object getElementAt(int index) {
							return values[index];
						}
					});
					
				} catch (IOException e) {
					JOptionPane.showMessageDialog( null, "There was a problem fetching your file" );
				} catch(NullPointerException e){
					// User cancelled the action
				} catch (RecordManagerException e)
				{
					// User selected a file that has no btree
					fileLocationTxt.setText( "" );
					JOptionPane.showMessageDialog( GraphCreation.vv, "You selected a file that contains no Btree" );
					
				}
			}
			
			
		});
		GridBagConstraints gbc_fileChooseButton = new GridBagConstraints();
		gbc_fileChooseButton.fill = GridBagConstraints.HORIZONTAL;
		gbc_fileChooseButton.insets = new Insets(0, 0, 5, 0);
		gbc_fileChooseButton.gridx = 2;
		// Test
		gbc_fileChooseButton.gridy = 7;
		filePickPanel.add( fileChooseButton, gbc_fileChooseButton );
		
		
		JPanel nodeInformationPanel = new JPanel();
		treeVizualisationPanel.add( nodeInformationPanel );
		nodeInformationPanel.setLayout( new GridLayout(1, 0, 0, 0) );
		
		JScrollPane tableScrollPane = new JScrollPane();
		tableScrollPane.setViewportBorder(new LineBorder( new Color(0, 0, 0), 1, true) );
		nodeInformationPanel.add( tableScrollPane );
		
		informationTable = new JTable();
		informationTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
		tableScrollPane.setViewportView( informationTable );
		// We use a dynamic population of the map for the data
		informationTable.setModel( new GraphTableData() );
		
		
		JPanel statisticsPagePanel = new JPanel();
		tabbedPane.addTab("Visualize Statistics", null, statisticsPagePanel, null);
		statisticsPagePanel.setLayout(new BorderLayout(0, 0));
		statisticsPagePanel.add(new MetricPage());
		
	}
}
